package com.free.space.controller.activiti;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.free.space.service.activiti.LeaveService;
import com.free.space.service.activiti.VacationService;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Controller
@RequestMapping("act/")
public class ActivitiController {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private VacationService vacationService;
    @Autowired
    private IdentityService identityService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessEngine processEngine;
    @Autowired
    private HistoryService historyService;

    @Autowired
    private LeaveService leaveService;

    /**
     * 工作流测试页面跳转
     *
     * @return
     */
    @RequestMapping("activitiPage")

    public String activitiPage() {
        return "act/activiti.html";
    }

    /**
     * 启动指定流程
     *
     * @param request
     * @return
     */
    @RequestMapping("startProcess")
    @ResponseBody
    public String start(HttpServletRequest request) {
        /*用户id*/
        String userId = request.getParameter("userId");
        /*流程id*/
        String process = request.getParameter("process");
        /*请求天数*/
        int days = Integer.parseInt(request.getParameter("days"));
        /*业务id*/
        String formId = request.getParameter("formId");
        /*启动流程实例，字符串"process"是BPMN模型文件里process元素的id*/
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(process);
        /*流程实例启动后，流程会跳转到请假申请节点*/
        Task vacationApply = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        /*设置请假申请任务的执行人*/
        taskService.setAssignee(vacationApply.getId(), userId);
        Map<String, Object> args = new HashMap<>();
        args.put("days", days);
        args.put("formId", formId);
        taskService.complete(vacationApply.getId(), args);

        Map map = new HashMap();
        map.put("formId",formId);
        map.put("processinstanceid",processInstance.getProcessInstanceId());
        map.put("userid",userId);
        map.put("days",days);
        leaveService.saveLeaveProcess(map);
        return "ok";
    }

    /**
     * 描述: 根据用户id查询待办任务列表
     */
    @RequestMapping("findTasksByUserId")
    @ResponseBody
    public String findTasksByUserId(HttpServletRequest request) {
        String process = request.getParameter("process");
        String userId = request.getParameter("userId");
        List<Task> resultTask = taskService.createTaskQuery().processDefinitionKey(process).taskCandidateOrAssigned(userId).list();
        JSONArray jsonArr = new JSONArray();
        for (Task t : resultTask) {
            Map map = new HashMap();
            map.put("任务id", t.getId());
            map.put("任务名称", t.getName());
            map.put("执行单元id", t.getExecutionId());
            map.put("父任务id", t.getParentTaskId());
            map.put("实例id", t.getProcessInstanceId());
            jsonArr.add(JSON.toJSON(map));
        }
        return jsonArr.toJSONString();
    }

    /**
     * 审批
     *
     * @param request
     * @return
     */
    @RequestMapping("apply")
    @ResponseBody
    public String apply(HttpServletRequest request) {
        String userId = request.getParameter("userId");
        String taskId = request.getParameter("taskId");
        int auditResult = Integer.parseInt(request.getParameter("auditResult"));
        //查询当前审批节点
        Task vacationAudit = taskService.createTaskQuery().taskId(taskId).singleResult();
        Map map = new HashMap();
        String pocessInstanceId = vacationAudit.getProcessInstanceId();
        map.put("pocessInstanceId",pocessInstanceId);
        map.put("processStatus",auditResult);
        leaveService.updateLeaveResult(map);
        //审批通过
        if (auditResult == 1) {
            //设置流程参数：审批ID
            Map<String, Object> args = new HashMap<>();
            args.put("auditId", UUID.randomUUID().toString());
            //设置审批任务的执行人
            taskService.claim(vacationAudit.getId(), userId);
            //完成审批任务
            taskService.complete(vacationAudit.getId(), args);
        } else {
            //审批不通过，结束流程
            runtimeService.deleteProcessInstance(vacationAudit.getProcessInstanceId(), UUID.randomUUID().toString());
        }
        return "ok";
    }

    /**
     * 查看工作流程图
     *
     * @param response
     * @param processInstanceId
     */
    @RequestMapping(value = "/showImage", method = RequestMethod.GET)
    public void image(HttpServletResponse response,
                      @RequestParam String processInstanceId) {
        try {
            InputStream is = vacationService.getDiagram(processInstanceId);
            if (is == null)
                return;
            response.setContentType("image/png");
            BufferedImage image = ImageIO.read(is);
            OutputStream out = response.getOutputStream();
            ImageIO.write(image, "png", out);
            is.close();
            out.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 历史任务查询
     *
     * @param request
     */
    @RequestMapping(value = "/showHistoryTaskList", method = RequestMethod.GET)
    @ResponseBody
    public String showHistoryTaskList(HttpServletRequest request) {
        String processInstanceId = request.getParameter("processInstanceId");
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()// 创建历史任务实例查询
                .processInstanceId(processInstanceId) // 用流程实例id查询
                .finished() // 查询已经完成的任务
                .list();
        JSONArray jsonArr = new JSONArray();
        for (HistoricTaskInstance hti : list) {
            Map map = new HashMap();
            map.put("任务ID", hti.getId());
            map.put("流程实例ID", hti.getProcessInstanceId());
            map.put("任务名称", hti.getName());
            map.put("办理人", hti.getAssignee());
            map.put("开始时间", hti.getStartTime());
            map.put("结束时间", hti.getEndTime());
            jsonArr.add(JSON.toJSON(map));
        }
        return jsonArr.toJSONString();
    }

    /**
     * 查询流程状态
     *
     * @param request
     */
    @RequestMapping(value = "/showProcessState", method = RequestMethod.GET)
    @ResponseBody
    public String showProcessState(HttpServletRequest request) {
        String processInstanceId = request.getParameter("processInstanceId");
        ProcessInstance pi = runtimeService.createProcessInstanceQuery() // 创建流程实例查询
                .processInstanceId(processInstanceId) // 用流程实例id查询
                .singleResult();
        if (pi != null) {
            System.out.println("流程正在执行！");
            return pi.getLocalizedName();
        } else {
            System.out.println("流程已经执行结束！");
            return "流程已经执行结束！";
        }
    }

    /**
     * 获取当前任务
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/showCurrentTask", method = RequestMethod.GET)
    @ResponseBody
    public String showCurrentTask(HttpServletRequest request) {
        String taskId = request.getParameter("taskId");
        HistoricTaskInstance currTask = historyService.createHistoricTaskInstanceQuery()
                .taskId(taskId)
                .singleResult();
        return null;
    }


    /**
     * 用户，角色同工作流绑定
     */
    @RequestMapping(value = "/userAndRoleActivitiMapp", method = RequestMethod.GET)
    @ResponseBody
    public void userAndRoleActivitiMapp() {
        //项目中每创建一个新用户，对应的要创建一个Activiti用户
        //两者的userId和userName一致
        User admin = identityService.newUser("1");
        admin.setLastName("admin");
        identityService.saveUser(admin);

        //项目中每创建一个角色，对应的要创建一个Activiti用户组
        Group adminGroup = identityService.newGroup("1");
        adminGroup.setName("admin");
        identityService.saveGroup(adminGroup);
        //用户与用户组关系绑定
        identityService.createMembership("1", "1");
    }
}
